/**
 * MCU 适配层
 */

#pragma once

#include <stddef.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>

#ifdef __cplusplus
extern "C" {
#endif


#define getPointer(stream) (*((void**)stream))

// A53 是小端模式
#define __LITTLE_ENDIAN__ 1

#if (__LITTLE_ENDIAN__ == 1)
	// 网络字节顺序采用 big endian 排序方式
	// 所以如果 MCU 的字节序是 little endian 方式时，需要进行转换
	#define ntoh32(dw) 	BL32(dw)
	#define ntoh16(w) 	BL16(w)
	#define hton32(dw) 	BL32(dw)
	#define hton16(w) 	BL16(w)

	// 从一个字节流中，读取32/16位整数(无符号/有符号)，解决字节对齐问题，同时解决字节序问题
	uint32_t getU32(const void *stream);
	uint16_t getU16(const void *stream);

	#define getS32(stream) ((int32_t)getU32(stream))
	#define getS16(stream) ((int16_t)getU16(stream))
#else
	#define ntoh32(dw) 	(dw)
	#define ntoh16(w) 	(w)
	#define hton32(dw) 	(dw)
	#define hton16(w) 	(w)

	// 从一个字节流中，读取32/16位整数(无符号/有符号)，解决字节对齐问题，同时解决字节序问题
	#define getU32(stream) (*((uint32_t*)stream))
	#define getU16(stream) (*((uint16_t*)stream))

	#define getS32(stream) (*((int32_t*)stream))
	#define getS16(stream) (*((int16_t*)stream))
#endif

/// 是否处于调试状态
int osIsInDebugMode();
/// 获得启动模式
uint32_t osGetBootMode();
/// 获得重启原因
uint32_t osGetResetReason();
/// 是否是非正常重启
int osIsAbnormalReboot();
/// 软件重启 PS
void osSystemReboot();

/**
 * 获取芯片的唯一 ID（这里是 FPGA 中的 DNA）
 * 参考 https://zhuanlan.zhihu.com/p/527204236
 */
std_err_t osGetChipId(uint8_t id[12]);

/// MCU 初始化
std_err_t mcu_init();


#ifdef __cplusplus
}
#endif
